package com.hdhere.core.security.shiro;

import com.hdhere.domain.common.util.LoginUtils;
import org.apache.shiro.web.filter.mgt.FilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

public class MyPathMatchingFilterChainResolver extends PathMatchingFilterChainResolver {

    private static final Logger logger = LoggerFactory.getLogger(MyPathMatchingFilterChainResolver.class);

    private MyDefaultFilterChainManager customDefaultFilterChainManager;

    public void setCustomDefaultFilterChainManager(MyDefaultFilterChainManager customDefaultFilterChainManager) {

        this.customDefaultFilterChainManager = customDefaultFilterChainManager;
        setFilterChainManager(customDefaultFilterChainManager);
    }

    public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if (httpRequest.getMethod().equalsIgnoreCase("options")) { // 对于复杂跨域请求的预请求(preflight request)，直接通过。
            return null;
        }

        FilterChainManager filterChainManager = getFilterChainManager();
        if (!filterChainManager.hasChains()) {
            return null;
        }

        String requestURI = getPathWithinApplication(request);

        List<String> chainNames = new ArrayList<String>();
        // the 'chain names' in this implementation are actually path patterns
        // defined by the user. We just use them
        // as the chain name for the FilterChainManager's requirements
        for (String pathPattern : filterChainManager.getChainNames()) {

            // If the path does match, then pass on to the subclass
            // implementation for specific checks:
            if (pathMatches(pathPattern, requestURI)) {
                chainNames.add(pathPattern);
                break;
            }
        }

        if (chainNames.size() == 0) {
            logger.error("No found the corresponding path mapping for " + requestURI);
            return null;
        }

        // 防止有些请求不会生成session。eg。/fooding-es/fc/language/getList
        //LoginUtils.getSession();

        return customDefaultFilterChainManager.proxy(originalChain, chainNames);
    }
}
